package com.bjpowernode.config.handler;

import com.bjpowernode.constant.Constants;
import com.bjpowernode.model.TUser;
import com.bjpowernode.result.LoginData;
import com.bjpowernode.result.R;
import com.bjpowernode.service.RedisService;
import com.bjpowernode.service.UserService;
import com.bjpowernode.util.JSONUtil;
import com.bjpowernode.util.JWTUtil;
import com.bjpowernode.util.ResponseUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Resource
    private RedisService redisService;

    @Resource
    private UserService userService;

    //spring容器提供好的线程池对象
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 登录成功后会调用该方法
     *
     * @param request
     * @param response
     * @param authentication
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //返回json

        //设置响应编码
        response.setCharacterEncoding("UTF-8");
        //设置响应内容类型(媒体类型)
        response.setContentType("application/json;charset=utf-8");

        //1、生成jwt
        TUser tUser = (TUser)authentication.getPrincipal();
        String loginUserJSON = JSONUtil.toJSON(tUser);
        String jwt = JWTUtil.createJWT(loginUserJSON);

        //2、把jwt写入redis
        redisService.setValue(Constants.REDIS_LOGIN_JWT_KEY + tUser.getId(), jwt, 30L, TimeUnit.MINUTES);

        //设置jwt的过期时间，如果选择了记住我，过期时间是7天，否则是30分钟
        String rememberMe = request.getParameter("rememberMe");
        if (Boolean.parseBoolean(rememberMe)) {
            redisService.expire(Constants.REDIS_LOGIN_JWT_KEY + tUser.getId(), Constants.EXPIRE_TIME, TimeUnit.MINUTES);
        } else {
            redisService.expire(Constants.REDIS_LOGIN_JWT_KEY + tUser.getId(), Constants.DEFAULT_EXPIRE_TIME, TimeUnit.MINUTES);
        }

        //更新登录时间（改成一个异步操作） 使用原始的Thread执行异步任务
        /*new Thread(() -> {
            userService.updateLoginTimeById(tUser.getId());
        }).start();*/

        //使用线程池异步执行任务
        threadPoolTaskExecutor.execute(() -> {
            userService.updateLoginTimeById(tUser.getId());
        });

        //返回JSON出去
        LoginData loginData = LoginData.builder().jwt(jwt).authList(tUser.getAuthoritieList()).build();
        R result = new R(200,"登录成功", loginData);

        //把result对象转成JSON
        String json = JSONUtil.toJSON(result);

        //结果写出去
        ResponseUtil.write(response, json);
    }
}
